package cn.good.yan.sf.t3;

import java.util.Iterator;
import java.util.function.Consumer;

/**
 * 3.链表 - 自定义 链表 - 双向链表 - 带哨兵  头 1  2  3  尾 （每个节点都有前后节点）
 * a 添加头节点（头插法） - addFirst（）
 * b 遍历 （有4种方式）
 * c 添加尾节点 （尾插法） - addLast（）
 * d 根据下标获取单条数据 - getIndex
 * e 根据索引添加数据 - addIndex
 * f 删除头元素 - removeFirst
 * g 删除指定元素 - （根据下标指定删除元素） - remove
 *
 * @author shengren.yan
 * @create 2024-05-01
 */
public class Demo3 implements Iterable<Integer> {

    private static class Node {
        private Node prev; //上一个节点
        private int value; //值
        private Node next; //下一个节点

        public Node(Node prev, int value, Node next) {
            this.prev = prev;
            this.value = value;
            this.next = next;
        }
    }

    private Node head;   // 头节点
    private Node tail;   // 尾节点

    public Demo3() {
        head = new Node(null, -11, null);
        tail = new Node(null, -22, null);
        head.next = tail;
        tail.prev = head;
//        head.prev = tail;
//        tail.next = head;
    }

    //  a 添加头节点（头插法） - addFirst（）
    public void addFirst(int element) {
//        Node next = head.next;
//        Node node = new Node(head, element, next);
//        head.next = node;
//        next.prev = node;
        // 等价于上面的
        addIndex(0, element);
    }

    //  b 遍历 （有4种方式）
    @Override
    public Iterator<Integer> iterator() {
        return new Iterator<Integer>() {
            Node n = head.next;

            @Override
            public boolean hasNext() {
                return n != tail;
            }

            @Override
            public Integer next() {
                int value = n.value;
                n = n.next;
                return value;
            }
        };
    }

    // b 遍历 （有1种方式）
    public void loop1() {
        Node n;
        for (n = head.next; n != tail; n = n.next) {
            System.out.println(n.value);
        }
    }

    // b 遍历 （有2种方式）
    public void loop2(Consumer<Integer> consumer) {
//        List<Integer> list = Lists.newArrayList();
//        list.stream().forEach();
        Node n;
        for (n = head.next; n != tail; n = n.next) {
            consumer.accept(n.value);
        }
    }

    // b 遍历 （有3种方式）
    public void loop3() {
        Node n = head.next;
        while (n != tail) {
            System.out.println(n.value);
            n = n.next;
        }
    }

    // c 添加尾节点 （尾插法） - addLast（）
    public void addLast(int element) {
        Node prev = tail.prev;
        Node node = new Node(prev, element, tail);
        tail.prev = node;
        prev.next = node;
    }

    // d 根据下标获取单条数据 - getIndex
    public int getIndex(int index) {
        Node node = getNode(index);
        if (node == null || node == head) {
            System.out.println("下标越界");
            return -1;
        }
        return node.value;
    }

    // 根据下标获取元素
    private Node getNode(int index) {
        Node n;
        int i = -1;
        for (n = head; n != tail; n = n.next) {
//            System.out.println(n.value + " - " + i);
            if (i == index) {
                return n;
            }
            i++;
        }
        return null; // 没找到
    }

    // e 根据索引添加数据 - addIndex
    public void addIndex(int index, int element) {
        Node prev = getNode(index - 1);
        if (prev == null) {
            System.out.println("下标越界");
            return;
        }
        Node next = prev.next;
        Node node = new Node(prev, element, next);
        prev.next = node;
        next.prev = node;
    }

    // f 删除头元素 - removeFirst
    public void removeFirst() {
        Node node = head.next;
        if (node == tail) {
            System.out.println("没有要删除的元素");
            return;
        }
        Node next = node.next;
        head.next = next;
        next.prev = head;
    }

    // g 删除指定元素 - （根据下标指定删除元素） - remove
    public void remove(int index) {
        Node prev = getNode(index - 1);
        if (prev == null) {
            System.out.println("下标越界");
            return;
        }
        Node node = prev.next;  // 被删除的节点
        if (node == null || node == tail) {
            System.out.println("下标越界");
            return;
        }
        Node next = node.next;
        prev.next = next;
        next.prev = prev;
    }


    public static void main(String[] args) {
        Demo3 d = new Demo3();
        // a 测试 - addFirst
//        d.addFirst(1);
//        d.addFirst(2);
//        d.addFirst(3);
//        System.out.println(d);
        //  b 遍历
//        d.loop1();
//        d.loop2(x -> {
//            System.out.println(x);
//        });
//        d.loop3();
//        for (Integer e : d) {
//            System.out.println(e);
//        }
        // c 添加尾节点 （尾插法） - addLast（）
//        d.addLast(1);
//        d.addLast(2);
//        d.addLast(3);
        System.out.println(d);

        // d 根据下标获取单条数据 - getIndex
//        System.out.println(d.getIndex(0));
//        System.out.println(d.getIndex(-1));
//        System.out.println(d.getIndex(1));
//        System.out.println(d.getIndex(2));
//        System.out.println(d.getIndex(3));

        // e 根据索引添加数据 - addIndex
//        d.addIndex(-1, 1);
//        d.addIndex(0, 1);
//        d.addIndex(1, 2);
//        d.addIndex(3, 20);
//        System.out.println(d);

        // f 删除头元素 - removeFirst
        d.addLast(1);
        d.addLast(2);
        d.addLast(3);
//        d.removeFirst();
        // 测试 g 删除指定元素 - （根据下标指定删除元素） - remove
        System.out.println(d);
//        d.remove(-1);
//        d.remove(0);
        d.remove(1);
        d.remove(5);
        System.out.println(d);

    }
}
